package com.lwj.utils;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class AopUtil {

	/**
	 * 获取被切面的类
	 * 
	 * @param pjp
	 * @return
	 */
	public static Class<?> pointClass(JoinPoint pjp) {
		return pjp.getTarget().getClass();
	}

	/**
	 * 获取被切面的方法
	 * 
	 * @param pjp
	 * @return
	 * @throws Exception
	 */
	public static Method pointMethod(JoinPoint pjp) throws Exception {
		Method result = null;
		Class<?> targetClass = pjp.getTarget().getClass();
		Signature signature = pjp.getSignature();
		if (signature instanceof MethodSignature) {
			MethodSignature methodSignature = (MethodSignature) signature;
			Class<?>[] paramTypes = methodSignature.getParameterTypes();
			String methodName = pjp.getSignature().getName();
			result = targetClass.getMethod(methodName, paramTypes);
		}
		return result;
	}

	/**
	 * 获取被切面类的注解
	 * 
	 * @param pjp
	 * @return
	 * @throws Exception
	 */
	public static Annotation[] pointClassAnnotation(JoinPoint pjp) {
		return pjp.getTarget().getClass().getAnnotations();
	}

	/**
	 * 获取被切面方法的注解
	 * 
	 * @param pjp
	 * @return
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws Exception
	 */
	public static Annotation[] pointMethodAnnotation(JoinPoint pjp) throws Exception {
		Method targetMethod = pointMethod(pjp);
		return targetMethod.getAnnotations();
	}

	/**
	 * 获取注解
	 * 
	 * @param <T>
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static <T extends Annotation> T annotation(Annotation[] annotations, Class<T> clazz) throws Exception {
		T t = null;
		for (Annotation annotation : annotations) {
			if (clazz.isAssignableFrom(annotation.getClass())) {
				t = (T) annotation;
				break;
			}
		}
		return t;
	}

	/**
	 * 获取注解
	 * 
	 * @param <T>
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
	public static <T extends Annotation> T annotation(JoinPoint pjp, Class<T> clazz) throws Exception {
		Annotation[] annotations = pointMethodAnnotation(pjp);
		T t = annotation(annotations, clazz);
		return t;
	}

	/**
	 * 获取注解
	 * 
	 * @param <T>
	 * @param method
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
	public static <T extends Annotation> T annotation(Method method, Class<T> clazz) throws Exception {
		Annotation[] annotations = method.getAnnotations();
		T t = annotation(annotations, clazz);
		return t;
	}

}
